import {useEffect, useRef} from 'react';
import './App.css';
import PaoPao from './PaoPao.ts';

const list: PaoPao[] = []; // 泡泡数组 有序数组
let movingPaoPao: PaoPao | null = null; // 正在移动的泡泡
const mouseOffset = {
    x: 0,
    y: 0
}

function App() {
    const canvasRef = useRef<HTMLCanvasElement>(null);
    const canvasWidth = 1200;
    const canvasHeight = 800;
    const paopaoRadius = 50;

    // 随机颜色生成函数
    const getRandomColor = () => {
        const r = Math.floor(Math.random() * 256);
        const g = Math.floor(Math.random() * 256);
        const b = Math.floor(Math.random() * 256);
        return `rgb(${r}, ${g}, ${b})`;
    };

    useEffect(() => {
        if(!canvasRef.current) {
            throw new Error('huiguo: Canvas is null');
        }

        let time = 0;
        const ctx = canvasRef.current.getContext('2d');

        if(!ctx) {
            throw new Error('huiguo: Canvas context is null');
        }

        ctx.lineWidth = 2;
        // 海洋效果
        const drawOcean = (ctx: CanvasRenderingContext2D, width: number, height : number, time: number) => {
            const gradient = ctx.createLinearGradient(0, 0, 0, height);//颜色从上到下渐变
            gradient.addColorStop(0, '#00bfff');
            gradient.addColorStop(1, '#1e90ff');
            ctx.fillStyle = gradient;
            ctx.fillRect(0, 0, width, height);//渐变背景

            ctx.beginPath();
            const waveHeight = 50;
            const waveLength = 100;
            const waveSpeed = time * 1.05;//海浪速度
            ctx.moveTo(0, height * 0.8);//画笔移动到左下方绘制海浪
            for (let x = 0; x <= width; x++) {
                const y = Math.sin((x + waveSpeed) / waveLength) * waveHeight + height * 0.8;//循环正弦波
                ctx.lineTo(x, y);//从当前点到xy
            }
            ctx.lineTo(width, height);//右下角
            ctx.lineTo(0, height);//左下角
            ctx.closePath();
            ctx.fillStyle = 'rgba(255, 255, 255, 0.3)';
            ctx.fill();
        };
        //
        // // 初始生成泡泡
        //     list.push(
        //         new PaoPao(
        //             -paopaoRadius,
        //             canvasHeight - paopaoRadius,
        //             canvasWidth,
        //             canvasHeight,
        //             ctx,
        //             getRandomColor()
        //         )
        //     );
        let rid = 0;

        const animate = () => {
            time++;
            ctx.clearRect(0, 0, canvasWidth, canvasHeight);
            drawOcean(ctx, canvasWidth, canvasHeight, time);

            // 更新并绘制泡泡
            for (const p of list) {
                p.move();
                p.draw();
            }

           rid = requestAnimationFrame(animate);
        };
         rid = requestAnimationFrame(animate);

        for (let i = 0; i < 20; i++) {
            list.push(
                new PaoPao(
                    Math.random() * (canvasWidth -paopaoRadius * 2) + paopaoRadius,
                    Math.random() * (canvasHeight -paopaoRadius * 2) + paopaoRadius,
                    canvasWidth,
                    canvasHeight,
                    ctx,
                    getRandomColor()
                )
            );
        }

        // [0,1,2...18,19];
        // [0,1,3...,17,18,19,2];


        const handleZIndex = (p: PaoPao) => {
            const index = list.findIndex(
                item => item === p
            );
            list.splice(index, 1); // 移除当前泡泡
            list.push(p); // 重新添加到数组末尾

        }

        const onDown = (e: MouseEvent) => {
            const {offsetX: x, offsetY: y} = e;
            const reversedList = [...list].reverse(); // 倒序遍历泡泡数组

            for (const p of reversedList) {
                const s = p.calculateDistanceWithPoint(x, y);
                if(s <= paopaoRadius) {
                    movingPaoPao = p;
                    mouseOffset.x = x - p.getPosition().x;
                    mouseOffset.y = y - p.getPosition().y;

                    handleZIndex(p); // 调整泡泡层级
                    break;
                }
            }
        }

        const onMove = (e: MouseEvent) => {
            const {offsetX: x, offsetY: y} = e;
            if(movingPaoPao !== null) {
                movingPaoPao.setPosition(x - mouseOffset.x, y - mouseOffset.y);
            }
        }

        const onUp = () => {
            movingPaoPao = null;
        }

        canvasRef.current.addEventListener('mousedown', onDown);
        canvasRef.current.addEventListener('mousemove', onMove);
        canvasRef.current.addEventListener('mouseup', onUp);

        return () => {
            cancelAnimationFrame(rid);
            canvasRef.current!.removeEventListener('mousedown', onDown);
            canvasRef.current!.removeEventListener('mousemove', onMove);
            canvasRef.current!.removeEventListener('mouseup', onUp);
        }
    }, []);

    return (
        <canvas
            ref={canvasRef}
            id="mc"
            width={canvasWidth}
            height={canvasHeight}
            style={{ border: '5px solid black' }}
        />
    );
}

export default App;